package online.heycm.platform.threadpool;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 线程池
 *
 * @author heycm
 * @since 2023/11/10 22:59
 */
public class WorkerPoolExecutor {

    /**
     * 线程池
     */
    private final ThreadPoolExecutor threadPoolExecutor;

    /**
     * 默认线程池名称
     */
    private static final String DEFAULT_WORKER_POOL_NAME = "worker-pool";

    /**
     * 通用设置
     *
     * @param workerPoolName           线程池名称
     * @param coreSize                 即使空闲时仍保留在池中的线程数
     * @param maxSize                  池中允许的最大线程数
     * @param queueCapacity            队列最大元素
     * @param keepAliveTime            当线程数大于内核时，这是多余的空闲线程在终止前等待新任务的最大时间
     * @param rejectedExecutionHandler 满队时拒绝策略
     * @param afterExecutionHandler    线程执行完成/异常监听处理器
     */
    public WorkerPoolExecutor(String workerPoolName, int coreSize, int maxSize, int queueCapacity, int keepAliveTime,
            RejectedExecutionHandler rejectedExecutionHandler, AfterExecutionHandler afterExecutionHandler) {
        threadPoolExecutor = new ThreadPoolExecutor(coreSize, maxSize, keepAliveTime, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(queueCapacity),
                new WorkerThreadFactory(workerPoolName),
                rejectedExecutionHandler) {
            @Override
            protected void afterExecute(Runnable r, Throwable t) {
                super.afterExecute(r, t);
                afterExecutionHandler.afterExecute(r, t);
            }
        };
    }

    /**
     * 通用设置
     *
     * @param coreSize                 即使空闲时仍保留在池中的线程数
     * @param maxSize                  池中允许的最大线程数
     * @param queueCapacity            队列最大元素
     * @param keepAliveTime            当线程数大于内核时，这是多余的空闲线程在终止前等待新任务的最大时间
     * @param rejectedExecutionHandler 满队时拒绝策略
     * @param afterExecutionHandler    线程执行完成/异常监听处理器
     */
    public WorkerPoolExecutor(int coreSize, int maxSize, int queueCapacity, int keepAliveTime,
            RejectedExecutionHandler rejectedExecutionHandler, AfterExecutionHandler afterExecutionHandler) {
        threadPoolExecutor = new ThreadPoolExecutor(coreSize, maxSize, keepAliveTime, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(queueCapacity),
                new WorkerThreadFactory(DEFAULT_WORKER_POOL_NAME),
                rejectedExecutionHandler) {
            @Override
            protected void afterExecute(Runnable r, Throwable t) {
                super.afterExecute(r, t);
                afterExecutionHandler.afterExecute(r, t);
            }
        };
    }

    /**
     * 执行任务
     *
     * @param command 任务
     */
    public void execute(Runnable command) {
        threadPoolExecutor.execute(command);
    }
}
